mod msgpack;

use crate::protocols::msgpack::MsgpackProtocolBuffer;
use crate::Result;
use alloc::vec::Vec;

pub use rmpv::ValueRef;

#[derive(Debug, Copy, Clone)]
pub enum TransportType {
    Auto,
    Json,
    Msgpack,
}

pub trait Transport: Send + Sync {
    fn serialize(&self, tt: TransportType, buff: &mut dyn TransportWrite) -> Result<()>;
    fn deserialize(&self, tt: TransportType, buff: &dyn TransportRead) -> Result<()>;
}

pub trait TransportRead {
    fn read<'a>(&mut self, data: &'a [u8]) -> Result<ValueRef<'a>>;
}

pub trait TransportWrite {
    fn payload(&mut self) -> &mut Vec<u8>;
    fn flush(self) -> Result<Vec<u8>>;
}

#[macro_export]
macro_rules! impl_write {
    ($tt:ident, $ty: ty) => {
        fn $tt(&mut self, v: &$ty) -> Result<()> {
            let v1 = unsafe {
                core::slice::from_raw_parts(v as *const $ty as *const u8, core::mem::size_of_val(v))
            };
            self.write(v1)
        }
    };
}

pub fn create_writer(limit: usize, tt: TransportType) -> impl TransportWrite {
    return MsgpackProtocolBuffer::new(limit, tt);
}

pub fn create_reader(_data: &[u8], _tt: TransportType) -> impl TransportRead {
    return MsgpackProtocolBuffer::new_reader();
}
